// system.h 
//	All global variables used in Nachos are defined here.
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef SYSTEM_H
#define SYSTEM_H

#include "copyright.h"
#include "utility.h"
#include "thread.h"
#include "scheduler.h"
#include "interrupt.h"
#include "stats.h"
#include "timer.h"
#include "synch.h"
#include "machine.h"
// Initialization and cleanup routines
extern void Initialize(int argc, char **argv); 	// Initialization,
						// called before anything else
extern void Cleanup();				// Cleanup, called when
						// Nachos is done.

extern Thread *currentThread;			// the thread holding the CPU
extern Thread *threadToBeDestroyed;  		// the thread that just finished
extern Scheduler *scheduler;			// the ready list
extern Interrupt *interrupt;			// interrupt status
extern Statistics *stats;			// performance metrics
extern Timer *timer;				// the hardware alarm clock


#ifdef USE_TLB
#include "ipt.h"
#include "bitmap.h"
#include "filesys.h"
#include "PageTableEntry.h"
#endif

extern bool PRAND;
extern bool PFIFO;

#ifdef USER_PROGRAM
#include "machine.h"
#include "bitmap.h"
extern Machine* machine;	// user program memory and registers
extern BitMap *usedpages;				//bitmap to manage pagetable
extern Lock *MainMemoryLock;
extern Lock *sysLock;

#ifdef NETWORK
extern int NUM_SERVERS;
extern int netname;
class ProcessTableEntry{
	public:
	
	AddrSpace* parentAddrSpace; /* Address Space of the process */
	int numAliveThreads; /* number of alive threads */
	Lock* processTableEntryLock; /* lock for the process table entry */
	
	ProcessTableEntry(AddrSpace* a){
		processTableEntryLock = new Lock("Process Table Entry Lock");
		parentAddrSpace = a;
		numThreads = 1;
		numAliveThreads = 1;
	}
	
	int getNumThreads(){
		return numThreads;
	}
	
	void setNumThreads(int n){
		numThreads = n;
	}
	
	void incrementNumThreads(){
		numThreads = numThreads+1;
	}
	
	void decrementNumThreads(){
		numThreads = numThreads-1;
	}
	
	private:
	int numThreads; /* number of threads in the process */
};
#else

struct ProcessTableEntry{
	AddrSpace* parentAddrSpace; /* Address Space of the process */
	int numThreads; /* number of threads in the process */
	int numAliveThreads; /* number of alive threads */
	Lock* processTableEntryLock; /* lock for the process table entry */
	
	ProcessTableEntry(AddrSpace* a){
		processTableEntryLock = new Lock("Process Table Entry Lock");
		parentAddrSpace = a;
		numThreads = 1;
		numAliveThreads = 1;
	}
	
};
#endif

const int MAX_PROCESSES = 15;
const int MAX_THREADS = 100;
//#define MAX_LOCKS 500
//#define MAX_CONDITIONS 500
//#define MAX_PROCESSES 5
//#define MAX_THREADS 75

extern Lock* processTableLock;
extern ProcessTableEntry* processTable[MAX_PROCESSES]; 

extern int nextProcessIndex; /* used by exec to assign process index, globalize this */
extern int numProcesses; /* used by exit to check the number of processes left */

#endif

#ifdef USE_TLB
extern IPTEntry ipt[NumPhysPages];
extern Lock	*iptLock;
extern int spacecounter;
extern BitMap	*iptUsedPages;
extern Lock	*bitMapLock;
extern int swapUsedPages;
extern Lock	*swapLock;
extern OpenFile	*swapfile;
extern List *fifoPages;
#endif

#ifdef FILESYS_NEEDED 		// FILESYS or FILESYS_STUB 
#include "filesys.h"
extern FileSystem  *fileSystem;
#endif

#ifdef FILESYS
#include "synchdisk.h"
extern SynchDisk   *synchDisk;
#endif

#ifdef NETWORK
#include "post.h"
extern PostOffice* postOffice;
#endif

#endif // SYSTEM_H
